package org.bigmarketapi.projectreview.CompletableFuture;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.concurrent.CompletableFuture;

/**
 * @BelongsProject: ProjectReview
 * @BelongsPackage: org.bigmarketapi.projectreview.CompletableFuture
 * @Author: dujiaqi
 * @CreateTime: 2024-09-08  14:52
 * @Description: TODO
 * @Version: 1.0
 */
public class demo2 {


    public static void main(String[] args) {
        
        final CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            log("cf1");
            return 1;
        }).thenCompose(result -> CompletableFuture.supplyAsync(() -> {
            log(result);
            log("cf2");
            return 2;
        })).exceptionally(e -> {
            log("Exception in first stage: " + e.getMessage());
            return null;
        });
    
        final CompletableFuture<Double> future1 = future.thenApplyAsync(result -> {
            log("2.1");
            return 2.1;
        }).exceptionally(e -> {
            log("Exception in future1: " + e.getMessage());
            return null;
        });
    
        final CompletableFuture<Double> future2 = future.thenApplyAsync(result -> {
            log("2.2");
            return 2.2;
        }).exceptionally(e -> {
            log("Exception in future2: " + e.getMessage());
            return null;
        });
    
        final CompletableFuture<Integer> future3 = future.thenComposeAsync(result -> CompletableFuture.supplyAsync(() -> {
            log("cf: "+result);
            log("3");
            return 3;
        })).exceptionally(e -> {
            log("Exception in future3: " + e.getMessage());
            return null;
        });
    
        final CompletableFuture<Integer> future4 = future3.thenCombineAsync(future, (cf1, cf2) -> {
            log("cf1: " + cf1 + ", cf2: " + cf2);
            log("4");
            return 4;
        }).exceptionally(e -> {
            log("Exception in future4: " + e.getMessage());
            return null;
        });
    
        final CompletableFuture<Integer> allFutures = CompletableFuture.allOf(future, future1, future2, future4)
            .thenApplyAsync(v -> {
                log("future: " + future.join());
                log("future1: " + future1.join());
                log("future4: " + future4.join());
                return future4;
            }).exceptionally(e -> {
                log("Exception in all futures: " + e.getMessage());
                return null;
            }).join();
    
        final Integer now = allFutures.getNow(0);
        log(now);
    }

    private static void log(Object message) {
        System.out.println(message);
    }
}

    